from functools import cached_property
import logging
import os
from pathlib import Path
from typing import ClassVar
from pydantic import BaseModel
from pysam import tabix_index  # pylint: disable=E0611

from .anno import Annotator


logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger("ClinSV")


class DELLY(BaseModel):
    data_dir: ClassVar[Path] = Path(__file__).parent / "data"
    bam_file: Path
    outdir: Path
    genome_file: Path
    genome_builder: str
    genepred_file: Path | None
    gene_id_file: Path | None

    @cached_property
    def sample(self) -> Path:
        return self.bam_file.stem.split(".", 1)[0]

    @cached_property
    def exclude_region_file(self) -> Path:
        return self.data_dir / f"{self.genome_builder}.exclude.tsv"

    @cached_property
    def bcf_file(self) -> Path:
        return self.outdir / f"{self.sample}.delly.bcf"

    @cached_property
    def vcf_file(self) -> Path:
        return self.outdir / f"{self.sample}.sv.vcf.gz"

    def do_delly(self):
        if not self.bcf_file.exists():
            command = f"delly call -g {self.genome_file} -o {self.bcf_file} -x {self.exclude_region_file} -t INV,BND {self.bam_file}"
            logger.info("Do DELLY to %s with command: '%s'", self.bcf_file, command)
            if os.system(command) > 0:
                raise RuntimeError(f"delly call failed: {command}")
        tabix_index(str(self.bcf_file), preset="vcf", force=True)

    def do_annotation(self):
        logger.info("Do Annotation to %s", self.vcf_file)
        Annotator(bcf_file=self.bcf_file, vcf_file=self.vcf_file, genepred_file=self.genepred_file, gene_id_file=self.gene_id_file).run()

    def run(self):
        self.do_delly()
        self.do_annotation()
